﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Xml;
using System.IO;
using System.Windows.Forms;

namespace avs2bdnxml_gui
{
    public class Bdn
    {
        private readonly XmlDocument _bdnxml;
        private readonly string _bdnfile;
        private readonly Common.Resolution _res;
        private readonly double _fps;
        #region Constructor
        public Bdn(string fname, double fps, Common.Resolution res)
        {
            this._bdnxml = new XmlDocument();
            this._bdnxml.Load(fname);
            this._bdnfile = fname;
            this._fps = fps;
            this._res = res;
        }
        #endregion
        #region Class BDNXML
        public class BdnXml
        {
            
            public BdnHeader BdnHeader { get; set; }
            public List<BdnEvent> BdnEvents { get; set; }

            public BdnXml()
            {
                this.BdnHeader = new BdnHeader();
                this.BdnEvents = new List<BdnEvent>();
            }

        }
        #endregion

        #region Class BDNHeader
        public class BdnHeader
        {
            public string Content { get; set; }
            public string Code { get; set; }
            public string VideoFormat { get; set; }
            public double FrameRate { get; set; }
            public string DropFrame { get; set; }
            public string FirstEventInTc { get; set; }
            public string LastEventOutTc { get; set; }
            public string ContentInTc { get; set; }
            public string ContentOutTc { get; set; }
            public string Type { get; set; }

        }
        #endregion
        #region Class BDNEvent
        public class BdnEvent
        {
            public string Forced { get; set; }
            public string InTc { get; set; }
            public string OutTc { get; set; }
            public string Width { get; set; }
            public string Height { get; set; }
            public string X { get; set; }
            public string Y { get; set; }
            public string GraphicFile { get; set; }

        }
        #endregion
        #region Methods

        public void SaveBdn()
        {
            this._bdnxml.Save(this._bdnfile);
        }

        public void SetBdnEventCount(int pi)
        {
            var headNode = this._bdnxml.SelectSingleNode("/BDN/Description/Events");
            var eventCountNode = headNode?.Attributes?.GetNamedItem("NumberofEvents");
            long.TryParse(eventCountNode?.Value, out var ecount);
            ecount += pi;
            if (eventCountNode != null) eventCountNode.Value = ecount.ToString();
        }

        public string GetBdnLastOut()
        {
            var headNode = this._bdnxml.SelectSingleNode("/BDN/Description/Events");
            var lastOutNode = headNode?.Attributes?.GetNamedItem("LastEventOutTC");
            return lastOutNode?.Value;
        }

        public void InsertBdnEvent(string intc, string outtc)
        {
            var eventRoot = this._bdnxml.SelectSingleNode("/BDN/Events");
            var newEvent = this._bdnxml.CreateElement("Event");
            newEvent.SetAttribute("Forced", "False");
            newEvent.SetAttribute("InTC", intc);
            newEvent.SetAttribute("OutTC", outtc);
            var eventImg = this._bdnxml.CreateElement("Graphic");
            eventImg.InnerText = "0.png";
            eventImg.SetAttribute("Width", this._res.X.ToString());
            eventImg.SetAttribute("Height", this._res.Y.ToString());
            eventImg.SetAttribute("X", "0");
            eventImg.SetAttribute("Y", "0");
            newEvent.AppendChild(eventImg);
            eventRoot?.AppendChild(newEvent);
            this.SetBdnEventCount(1);
        }

        public void InsertBlack(bool bfirst, string pngfile, int eblacka = 1500)
        {
            if (!File.Exists(pngfile))
            {
                Common.SavePng(pngfile);
            }

            if (bfirst)
            {
                this.InsertBdnEvent("00:00:00:00", "00:00:00:08");
            }
            else
            {
                var lastout = this.GetBdnLastOut();
                var lastblkin = Common.PlusTc(lastout, this._fps, eblacka);
                var lastblkout = Common.PlusTc(lastblkin, this._fps, 30);
                this.InsertBdnEvent(lastblkin, lastblkout);
            }

        }

        #endregion
    }
}
